package com.airline.connection;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;

import com.airline.beans.*;

import javax.jws.WebService;

@WebService
public class AirlineSystemService {	
	DatabaseConnection db = new DatabaseConnection();	

	/**
	 * employeeLogin
	 * @param String employeeID
	 * @param String password
	 * @return Employee e
	 */
	public Employee employeeLogin(String employeeID, String password) {
		Employee employee = getEmployee(employeeID);
		
		//look for the employee in the database by their employeeID
		if (employee == null) {
			return null;
		}
		
		//now see if the employeeID and password are valid together
		if (employee.getPassword().equals(password) == false) {
			return null;
		}
		
		return employee;
	}
	
	/**
	 * customerLogin
	 * @param String customerID
	 * @param String password
	 * @return Customer c
	 */
	public Customer customerLogin(String customerID, String password) {
		Customer customer = getCustomer(customerID);
		
		//look for the customer in the database by their employeeID
		if (customer == null) {
			return customer;
		}
		
		//now see if the customerID and password are valid together
		if (customer.getPassword().equals(password) == false) {
			return null;
		}
		
		return customer;
	}
	
	/**
	 * logout
	 * @param String personID
	 * @return Boolean result
	 */
	public Boolean logout(String personID) {
		//take the person with this ID and delete their session information.
		return true;
	}
	
	/**
	 * createEmployee
	 * @param Employee e
	 * @return String employeeID
	 */
	public String createEmployee(Employee e) {
		String employeeID = "";
		
		if (e == null) {
			return null;
		}

		//check that a similar employee doesn't already exist
		Employee[] employeeSearchResult = searchEmployees(e, "0", "1");
		if (employeeSearchResult != null && employeeSearchResult.length != 0) {
			return null;
		}
		
		//otherwise perform the insert
		employeeID = db.createEmployee(e);
		return employeeID;
	}
	
	/**
	 * deleteEmployee
	 * @param String employeeID
	 * @return Boolean result
	 */
	public Boolean deleteEmployee(String employeeID) {
		//make sure valid ID
		if (employeeID == null || employeeID.equals("")) {
			return false;
		}
		
		//see if it exists to be deleted
		Employee employee = getEmployee(employeeID);
		if (employee == null)
		{
			return false;
		}
		
		//delete from the employee table, returning the result
		return db.deleteEmployee(convertIDToInteger(employeeID));
	}
	
	/**
	 * updateEmployee
	 * @param String employeeID
	 * @param Employee e
	 * @return Boolean result
	 */
	public Boolean updateEmployee(Employee e) {
		Boolean result = false;
		
		if (e == null) {
			return false;
		}
		
		//look for the employee in the database by their employeeID
		Employee employee = getEmployee(e.getPersonID());
		if (employee == null) {
			return false;
		}
		
		//check that a similar employee doesn't already exist
		Employee[] employeeSearchResult = searchEmployees(e, "0", "1");
		if (employeeSearchResult != null && employeeSearchResult.length != 0) {
			return false;
		}

		//otherwise perform the update
		result = db.updateEmployee(e);
		return result;
	}
	
	/**
	 * getEmployee
	 * @param String employeeID
	 * @return Employee e
	 */
	public Employee getEmployee(String employeeID) {
		if (employeeID == null) {
			return null;
		} else {
			return db.getEmployeeByID(convertIDToInteger(employeeID));
		}
	}
	
	/**
	 * createCustomer
	 * @param Customer c
	 * @return String customerID
	 * @throws DAOException 
	 */
	public String createCustomer(Customer c) {
		String customerID = null;
		
		if (c == null) {
			return null;
		}

		//check that a similar customer doesn't already exist
		Customer[] customerSearchResult = searchCustomers(c, "0", "1");
		if (customerSearchResult != null && customerSearchResult.length != 0) {
			return null;
		}
		
		//otherwise perform the insert
		customerID = db.createCustomer(c);
		return customerID;
	}
	
	/**
	 * deleteCustomer
	 * @param String customerID
	 * @return Boolean result
	 */
	public Boolean deleteCustomer(String customerID) {
		//make sure valid ID
		if (customerID == null || customerID.equals("")) {
			return false;
		}
		
		//see if it exists to be deleted
		Customer customer = getCustomer(customerID);
		if (customer == null)
		{
			return false;
		}
		
		//delete from the customer table, returning the result
		return db.deleteCustomer(convertIDToInteger(customerID));
	}
	
	/**
	 * updateCustomer
	 * @param Customer c
	 * @return Boolean result
	 */
	public Boolean updateCustomer(Customer c) 
	{
		Boolean result = true;
		//look for the customer in the database by their customerID
		Customer tempCustomer = getCustomer(c.getPersonID());
		if (tempCustomer == null) {
			return false;
		}
		
		//check that a similar employee doesn't already exist
//		Customer[] customerSearchResult = searchCustomers(c, "0", "1");
//		if (customerSearchResult != null && customerSearchResult.length != 0) {
//			return false;
//		}

		//otherwise perform the update
		result = db.updateCustomer(c);
		return result;
	}
	
	/**
	 * getCustomer
	 * @param String customerID
	 * @return Customer c
	 */
	public Customer getCustomer(String customerID) 
	{
		if (customerID == null || customerID.equals("")) {
			return null;
		} else {
			return db.getCustomerByID(convertIDToInteger(customerID));
		}	
	}
	
	/**
	 * createJourney
	 * @param Journey journey
	 * @return String journeyID/ticketNumber
	 */
	public String createJourney(Journey journey) 
	{
		String journeyID = null;
		
		if (journey == null) {
			return null;
		}

		//check that a similar journey doesn't already exist
//		Journey[] journeySearchResult = searchJourneys(journey);
//		if (journeySearchResult != null && journeySearchResult.length != 0) {
//			return null;
//		}
		
		//update the seatCounts for the flights
		String firstFlightID = journey.getFirstFlightID();
		Flight firstFlight = getFlight(firstFlightID);
		int firstFlightAvailSeats = Integer.parseInt(firstFlight.getAvailableSeatCount());
		
		String secondFlightID = journey.getSecondFlightID();
		Flight secondFlight = null;
		int secondFlightAvailSeats = 0;
		if (!secondFlightID.equals("0")) {
			secondFlight = getFlight(secondFlightID);
			secondFlightAvailSeats = Integer.parseInt(secondFlight.getAvailableSeatCount());
		}
		
		System.out.println("FirstFlight = " + firstFlightID + " SecondFlight = " + secondFlightID);
		
//		if (firstFlightAvailSeats > 0 && secondFlightID.equals("0")) {
//			firstFlight.setAvailableSeatCount(Integer.toString(firstFlightAvailSeats-1));
//			updateFlight(firstFlight);
//		} else if (firstFlightAvailSeats > 0 && secondFlightAvailSeats > 0) {
//			firstFlight.setAvailableSeatCount(Integer.toString(firstFlightAvailSeats-1));
//			updateFlight(firstFlight);
//			secondFlight.setAvailableSeatCount(Integer.toString(secondFlightAvailSeats-1));
//			updateFlight(secondFlight);
//		} else {
//			return null; //could not find seats, so could not make reservation
//		}
		
		//otherwise perform the insert
		journeyID = db.createJourney(journey);
		return journeyID;
	}
	
	/**
	 * cancelJourney (like deleteJourney)
	 * @param String journeyID
	 * @return Boolean result
	 */
	public Boolean cancelJourney(String journeyID) {
		//make sure valid ID
		if (journeyID == null || journeyID.equals("")) {
			return false;
		}
		
		//see if it exists to be deleted
		Journey journey = getJourney(journeyID);
		if (journey == null)
		{
			return false;
		}
		
		//update the seatCounts for the flights
		String firstFlightID = journey.getFirstFlightID();
		Flight firstFlight = getFlight(firstFlightID);
		int seatCount = Integer.parseInt(firstFlight.getAvailableSeatCount()) + 1;
		firstFlight.setAvailableSeatCount(Integer.toString(seatCount));
		updateFlight(firstFlight);
		
		String secondFlightID = journey.getSecondFlightID();
		if (!secondFlightID.equals("0")) {
			Flight secondFlight = getFlight(secondFlightID);
			int newCount = Integer.parseInt(secondFlight.getAvailableSeatCount()) + 1;
			secondFlight.setAvailableSeatCount(Integer.toString(newCount));
			updateFlight(secondFlight);
		}
		
		//delete the journey returning the result
		return db.deleteJourney(Integer.parseInt(journeyID));
	}
	
	/**
	 * getJourney
	 * @param String journeyID
	 * @return Journey j
	 */
	public Journey getJourney(String journeyID) {
		if (journeyID == null || journeyID.equals("")) {
			return null;
		} else {
			return db.getJourneyByID(Integer.parseInt(journeyID));
		}	
	}
	
	/**
	 * createFlight
	 * @param Flight f
	 * @return String flightID
	 */
	public String createFlight(Flight flight) {
		String flightID = null;

		//check that a similar flight doesn't already exist
		Flight[] flightSearchResult = searchFlights(flight, "0", "1");

		if (flightSearchResult != null && flightSearchResult.length != 0) {
			return null;
		}

		//otherwise perform the insert
		flightID = db.createFlight(flight);

		return flightID;
	}
	
	/**
	 * deleteFlight
	 * @param String flightID
	 * @return Boolean result
	 */
	public Boolean deleteFlight(String flightID) {
		//make sure valid ID
		if (flightID == null || flightID.equals("")) {
			return false;
		}
		
		//see if it exists to be deleted
		Flight flight = getFlight(flightID);
		if (flight == null)
		{
			return false;
		}
		
		//delete the flight returning the result
		return db.deleteFlight(Integer.parseInt(flightID));
	}
	
	/**
	 * updateFlight
	 * @param Flight f
	 * @return Boolean result
	 */
	public Boolean updateFlight(Flight flight) {
		Boolean result = false;
		
		if (flight == null) {
			return false;
		}
		
		//look for the employee in the database by their employeeID
		Flight tempFlight = getFlight(flight.getFlightID());
		if (tempFlight == null) {
			return false;
		}
		
		//check that a similar employee doesn't already exist
		Flight[] flightSearchResult = searchFlights(flight, "0", "1");
		if (flightSearchResult != null && flightSearchResult.length != 0) {
			return false;
		}

		//otherwise perform the update
		result = db.updateFlight(flight);
		return result;
	}
	
	/**
	 * getFlight
	 * @param String flightID
	 * @return Flight f
	 */
	public Flight getFlight(String flightID) {
		if (flightID == null || flightID.equals("") || flightID.equals("0")) {
			return null;
		} else {
			return db.getFlightByID(Integer.parseInt(flightID));
		}
	}
	
	/**
	 * getAllEmployees
	 * @return Employee[] employees
	 */
	public Employee[] getAllEmployees(String startingPoint, String numOfRecords) {
		return searchEmployees(null, startingPoint, numOfRecords);		
	}
	
	/**
	 * getAllCustomers
	 * @return Customer[] customers
	 */
	public Customer[] getAllCustomers(String startingPoint, String numOfRecords) {
		return searchCustomers(null, startingPoint, numOfRecords);
	}
	
	/**
	 * getAllFlights
	 * @return Flight[] flights
	 */
	public Flight[] getAllFlights(String startingPoint, String numOfRecords) {
		return searchFlights(null, startingPoint, numOfRecords);
	}
	
	/**
	 * getAllJourneys
	 * @return Journey[] journeys
	 */
	public Journey[] getAllJourneys() {
		return searchJourneys(null);
	}
	
	/**
	 * searchEmployees
	 * @param Employee e
	 * @return Collection employees
	 */
	public Employee[] searchEmployees(Employee e, String startingPoint, String numOfRecords) {
		return db.searchEmployees(e, Integer.parseInt(startingPoint), Integer.parseInt(numOfRecords));
	}
	
	/**
	 * searchCustomers
	 * @param Customer c
	 * @return Customer[] customers
	 */
	public Customer[] searchCustomers(Customer c, String startingPoint, String numOfRecords) {
		return db.searchCustomers(c, Integer.parseInt(startingPoint), Integer.parseInt(numOfRecords));
	}
	
	/**
	 * searchFlights
	 * @param Flight f
	 * @return Flight[] flights
	 */
	public Flight[] searchFlights(Flight flight, String startingPoint, String numOfRecords) {
		return db.searchFlights(flight, Integer.parseInt(startingPoint), Integer.parseInt(numOfRecords));
	}
	
	/**
	 * searchFlightItineraries
	 * @param Flight flight
	 * @return Journey[] flightItineraries
	 */
	public Journey[] searchFlightItineraries(Flight flight, String startingPoint, String numOfRecords) {
		Journey[] flightItineraries = null;
			if (flight == null) {
				return null;
			}
			
			//check that all search components are present
			String airlineName = flight.getAirlineName();
			String source = flight.getSource();
			String destination = flight.getDestination();
			if (!airlineName.equals("") && !source.equals("") && !destination.equals("")) {
				flightItineraries = db.searchItineraries(flight, Integer.parseInt(startingPoint), Integer.parseInt(numOfRecords));
			}
		
		return flightItineraries;
	}
	
	/**
	 * searchJourneys
	 * @param Journey j
	 * @return Journey[] journeys
	 */
	public Journey[] searchJourneys(Journey journey) {
		return db.searchJourneys(journey);
	}

	
	/**
	 * getAllCustomersByFlightID
	 * @param String flightID
	 * @return Customer[] customersOnFlight
	 */
	public Customer[] getAllCustomersByFlightID(String flightID) {
		Customer[] customersOnFlight = null;
		
		if (flightID == null || flightID.equals("")) {
			return null;
		}
		
		//search journeys for the flightID
		
		Journey tempJourney1 = new Journey("","","","","",flightID,"","","","","","","","","","");
		Journey[] journeysWithFlightIDFlight1 = db.searchJourneys(tempJourney1);
		Journey tempJourney2 = new Journey("","","","","","","","","","","","",flightID,"","","");
		Journey[] journeysWithFlightIDFlight2 = db.searchJourneys(tempJourney2);
		
		ArrayList<String> customerIDs = new ArrayList<String>();
		
		//loop through first array
		if (journeysWithFlightIDFlight1 != null) {
			for (int i = 0; i < journeysWithFlightIDFlight1.length; i++) {
				customerIDs.add(journeysWithFlightIDFlight1[i].getCustomerID());
			}
		}
		//loop through second array
		if (journeysWithFlightIDFlight2 != null) {
			for (int i = 0; i < journeysWithFlightIDFlight2.length; i++) {
				customerIDs.add(journeysWithFlightIDFlight2[i].getCustomerID());
			}
		}
		
		//process each customerID into a Customer object to be returned
		ArrayList<Customer> customers = new ArrayList<Customer>();
		for (int i = 0; i < customerIDs.size(); i++) {
			Customer tempCustomer = db.getCustomerByID(convertIDToInteger(customerIDs.get(i)));
			customers.add(tempCustomer);
		}
		
		if (customers.size() > 0) {
			Object[] objects = customers.toArray();
			customersOnFlight = new Customer[customers.size()];
			
			for (int i = 0; i < objects.length; i++) {
				customersOnFlight[i] = (Customer) objects[i];
			}
		}
		
		return customersOnFlight;
	}
	
	/**
	 * getAllFlightsByJourneyID
	 * @param String journeyID
	 * @return Flight[] flightsInJourney
	 */
	public Flight[] getAllFlightsByJourneyID(String journeyID) {
		Flight[] flightsInJourney = null;
		
		if (journeyID == null || journeyID.equals("")) {
			return null;
		}
		
		//get the journey
		Journey tempJourney = getJourney(journeyID);
		
		if (tempJourney == null) {
			return null;
		}
		
		Flight flight1 = getFlight(tempJourney.getFirstFlightID());
		Flight flight2 = getFlight(tempJourney.getSecondFlightID());
		
		if (flight1 != null && flight2 != null) {
			flightsInJourney = new Flight[2];
			flightsInJourney[0] = flight1;
			flightsInJourney[1] = flight2;
		} else if (flight1 != null && flight2 == null) {
			flightsInJourney = new Flight[1];
			flightsInJourney[0] = flight1;
		} else {
			return null;
		}
		
		return flightsInJourney;
	}
	
	/**
	 * getAllJourneysByCustomerID
	 * @param String customerID
	 * @return Journey[] journeysForCustomer
	 */
	public Journey[] getAllJourneysByCustomerID(String customerID) {
		Journey[] journeysForCustomer = null;
		
		if (customerID == null || customerID.equals("")) {
			return null;
		}

		Journey tempJourney = new Journey("","",customerID,"","","","","","","","","","","","","");
		
		journeysForCustomer = searchJourneys(tempJourney);
		
		return journeysForCustomer;
	}
	
	
	// HELPER METHODS:
	
	private int convertIDToInteger(String id) 
	{
		String noHyphenString = id.replaceAll("-", "");
		return Integer.parseInt(noHyphenString);		
	}
	
//	private String convertIDToString(int id)
//	{
//		//String integerString = Integer.toString(id);
//		String integerString = String.format("%09d", id);
//		String firstThree = integerString.substring(0, 3);
//		String nextTwo = integerString.substring(3, 5);
//		String lastFour = integerString.substring(5);
//		return firstThree + "-" + nextTwo + "-" + lastFour;
//	}
	
}